package com.hethongviet.vending.pages;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.hethongviet.vending.AppConfig;
import com.hethongviet.vending.AppMain;
import com.hethongviet.vending.Constant;
import com.google.android.DemoKit.R;
import com.hethongviet.vending.Utils;
import com.hethongviet.vending.helper.CodeResult;
import com.hethongviet.vending.helper.TimerOutUtils;
import com.hethongviet.vending.helper.db.AccountSQLite;
import com.hethongviet.vending.helper.db.BoxSQLite;
import com.hethongviet.vending.helper.db.MachineSQLite;
import com.hethongviet.vending.helper.db.ProductSQLite;
import com.hethongviet.vending.helper.dialog.DialogMessageBack;
import com.hethongviet.vending.helper.dialog.DialogMessageConfirm;
import com.hethongviet.vending.model.Account;
import com.hethongviet.vending.model.Box;
import com.hethongviet.vending.model.MachineInfo;
import com.hethongviet.vending.model.Product;
import com.hethongviet.vending.model.Transaction;
import com.hethongviet.vending.network.CONSTANTS;
import com.hethongviet.vending.network.CONSTANTS.ACCOUNT;
import com.hethongviet.vending.network.CONSTANTS.PRODUCT;
import com.hethongviet.vending.network.CONSTANTS.SERVICE;
import com.hethongviet.vending.network.CONSTANTS.STATUS;
import com.hethongviet.vending.network.Network;

public class ConfigMachineActivity extends GeneralActivity
{
	public static final int REQUEST_EDIT_MAC_ADDRESS = 5;

	private LinearLayout _listViewProduct = null;
	private LinearLayout _listViewAccount = null;

	private Button _buttonAddProduct = null;
	private Button _buttonAddAccount = null;

	private Button _buttonModifyDeviceNumber = null;

	private Button _buttonUpdateAccount = null;
	private Button _buttonUpdateProduct = null;
	private Button _buttonGetBoxConfig = null;

	private TextView _TextViewDeviceNumber = null;

	private TimerOutUtils _timerOutUtils = null;

	public AccountSQLite _accountSqLite = null;
	private ProductSQLite _productSqLite = null;

	public ConfigMachineActivity()
	{
		_accountSqLite = new AccountSQLite(this);
		_productSqLite = new ProductSQLite(this);
	}

	private static class ViewHolderAccount
	{
		TextView textAccountNumber = null;
		TextView textAccountName = null;
		Button buttonModify = null;
		Button buttonDelete = null;
	}

	private static class ViewHolderProduct
	{
		TextView textProductName = null;
		TextView textProductCode = null;
		Button buttonModify = null;
		Button buttonDelete = null;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setContentView(R.layout.page_service_config);

		findViewById(R.id.button_back).setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View arg0)
			{
				finish();
			}
		});

		// ((TextView) findViewById(R.id.text_user_name))
		// .setText(AppMain.getInstance()._accountCurrent.getName());

		((TextView) findViewById(R.id.text_user_name)).setVisibility(View.GONE);

		_listViewAccount = (LinearLayout) findViewById(R.id.config_list_account);
		_listViewProduct = (LinearLayout) findViewById(R.id.config_list_product);

		_buttonAddAccount = (Button) findViewById(R.id.button_config_add_account);
		_buttonAddProduct = (Button) findViewById(R.id.button_config_add_product);

		_buttonUpdateAccount = (Button) findViewById(R.id.button_service_update_account);
		_buttonUpdateProduct = (Button) findViewById(R.id.button_service_update_product);
		_buttonGetBoxConfig = (Button) findViewById(R.id.button_service_get_box_config);

		_buttonModifyDeviceNumber = (Button) findViewById(R.id.button_config_modify_device_number);

		_TextViewDeviceNumber = (TextView) findViewById(R.id.text_config_device_number);

		_TextViewDeviceNumber.setText(AppMain.getInstance().getMachineInfo().getPhoneNumber());

		/* Do not add client and product */
		_buttonAddAccount.setVisibility(View.GONE);
		_buttonAddProduct.setVisibility(View.GONE);

		_buttonUpdateAccount.setVisibility(View.GONE);
		_buttonUpdateAccount.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				if (AppConfig.IS_NETWORK_AVAILABLE)
				{
					Utils.debug("Update accounts!!!!!");

					Network.sendRequestUpdateAccount();
					showProgress(ConfigMachineActivity.this);
				}
			}
		});

		_buttonUpdateProduct.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				Utils.debug("Update products!!!!!");

				Network.sendRequestUpdateProduct();
				showProgress(ConfigMachineActivity.this);
			}
		});

		_buttonGetBoxConfig.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				Utils.debug("get box config!!!!!");

				Network.sendRequestBoxConfig(AppMain.getInstance().getMachineInfo().getCode());
				showProgress(ConfigMachineActivity.this);
			}
		});

		_buttonModifyDeviceNumber.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View arg0)
			{
				Utils.debug("Modified device number!!!!!");

				_timerOutUtils.pause();

				Intent intent = new Intent(ConfigMachineActivity.this,
						InputTextActivity.class);
				Bundle bundle = new Bundle();
				bundle.putInt(InputTextActivity.KEY_INPUT_TYPE,
						InputTextActivity.INPUT_DEVICE_NUMBER);
				bundle.putInt(Constant.EXTRA_FINISH, 2);
				intent.putExtras(bundle);
				startActivityForResult(intent,
						InputTextActivity.INPUT_DEVICE_NUMBER);
			}
		});

		_timerOutUtils = new TimerOutUtils(this, R.id.text_time, false);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		_timerOutUtils.startTimerNotOperating();

		return super.onTouchEvent(event);
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus)
	{
		switch (AppMain.getInstance().getCodeResult())
		{
			case TIME_OUT_NOT_OPERATOR:
				AppMain.getInstance().setNumberActivityFinishLogout(1);
				showDialogCatch(R.string.message_time_out_user_not_operating);

				break;
			case TIME_OUT_USER:
				AppMain.getInstance().setNumberActivityFinishLogout(1);
				showDialogCatch(R.string.message_time_out_user);

				break;
			default:
				break;
		}

		AppMain.getInstance().setCodeResult(CodeResult.NONE);

		super.onWindowFocusChanged(hasFocus);
	}

	private void showDialogCatch(final int id)
	{
		runOnUiThread(new Runnable()
		{
			@Override
			public void run()
			{
				try
				{
					showDialog(id);
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});

	}

	@Override
	protected Dialog onCreateDialog(int id)
	{
		if (id == R.string.message_time_out_user)
		{
			return new DialogMessageBack(this, true, id, true);
		}
		else if (id == R.string.message_time_out_user_not_operating)
		{

			final DialogMessageConfirm dialogMessageConfirmNotOperating = new DialogMessageConfirm(
					this, false, id, true);
			OnClickListener onClickListenerYESNotOperating = new OnClickListener()
			{

				@Override
				public void onClick(View v)
				{
					dialogMessageConfirmNotOperating.cancel();
					_timerOutUtils.stopTimeOutDialog();
					AppMain.getInstance().setNumberActivityFinishLogout(0);
				}
			};
			dialogMessageConfirmNotOperating.setOnclickListenerYes(onClickListenerYESNotOperating);
			return dialogMessageConfirmNotOperating;
		}
		else
			return createDialogStatusServer(id);
	}

	@Override
	protected void onPause()
	{
		_timerOutUtils.stop();

		super.onPause();
	}

	@Override
	public boolean dispatchKeyEvent(KeyEvent event)
	{
		if (KeyEvent.KEYCODE_MENU == event.getKeyCode()
				|| KeyEvent.KEYCODE_DPAD_LEFT == event.getKeyCode()
				|| KeyEvent.KEYCODE_DPAD_DOWN == event.getKeyCode()
				|| KeyEvent.KEYCODE_DPAD_RIGHT == event.getKeyCode()
				|| KeyEvent.KEYCODE_DPAD_UP == event.getKeyCode()
				|| KeyEvent.KEYCODE_DPAD_CENTER == event.getKeyCode()
				|| KeyEvent.KEYCODE_CALL == event.getKeyCode()
				|| KeyEvent.KEYCODE_CAMERA == event.getKeyCode()
				|| KeyEvent.KEYCODE_ENDCALL == event.getKeyCode()
				|| KeyEvent.KEYCODE_HOME == event.getKeyCode()
				|| KeyEvent.KEYCODE_SEARCH == event.getKeyCode()
				|| KeyEvent.KEYCODE_BACK == event.getKeyCode())
		{
			return Utils.disableAllKey(event);
		}
		else
			return super.dispatchKeyEvent(event);

	}

	@Override
	public void onAttachedToWindow()
	{
		if (AppConfig.USE_ATTACH_WINDOW_FOR_DISABLE_HOME_KEY)
		{
			this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
			super.onAttachedToWindow();
		}
	}

	@Override
	protected void onResume()
	{
		super.onResume();

		if (AppMain.getInstance().getNumberActivityFinishLogout() > 0)
		{
			AppMain.getInstance().setNumberActivityFinishLogout(
					AppMain.getInstance().getNumberActivityFinishLogout() - 1);
			finish();
			return;
		}

		_timerOutUtils.startTimerNotOperating();
		_timerOutUtils.startTimerOutUser();

		showListAccounts();

		showListProducts();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		if (resultCode == RESULT_OK)
		{
			if (data == null)
			{
				Utils.debug("null data return!!!!!!!!!!!!!!!!!!1");
				return;
			}

			String dataString = (requestCode != REQUEST_EDIT_MAC_ADDRESS) ? data.getStringExtra(InputTextActivity.KEY_INPUT_DATA)
					: data.getStringExtra(EditMacAddressActivity.EXTRA_MAC_ADDRESS);

			_timerOutUtils.resume();

			if (dataString == null || dataString.equals(""))
			{
				Utils.debug("null data String!!!!!!!!!!!!!!!!!!1");

				return;
			}

			final MachineSQLite machineSQLite = new MachineSQLite(this);
			MachineInfo machine = null;

			try
			{
				machine = machineSQLite.getAll().get(0);
			} catch (Exception e)
			{
				e.printStackTrace();
			}
			if (requestCode == InputTextActivity.INPUT_DEVICE_NUMBER)
			{
				_TextViewDeviceNumber.setText(dataString);
				machine.setPhoneNumber(dataString);

			}

			machineSQLite.insert(machine);
		}
	}

	private void showListAccounts()
	{

		_listViewAccount.removeAllViews();

		List<Account> accountsList = _accountSqLite.getAll();

		int totalAccounts = (accountsList != null) ? accountsList.size() : 0;

		if (totalAccounts != 0)
		{

			final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			for (int index = 0; index < totalAccounts; index++)
			{
				final View view = layoutInflater.inflate(
						R.layout.layout_config_one_client, null);

				final ViewHolderAccount holder = new ViewHolderAccount();
				holder.buttonDelete = (Button) view.findViewById(R.id.button_config_item_delete);
				holder.buttonModify = (Button) view.findViewById(R.id.button_config_item_modify);
				holder.textAccountName = (TextView) view.findViewById(R.id.config_item_client_name);
				holder.textAccountNumber = (TextView) view.findViewById(R.id.config_item_client_number);

				holder.textAccountName.setText(accountsList.get(index).getName());
				holder.textAccountNumber.setText(accountsList.get(index).getId());

				// not modified account
				holder.buttonDelete.setVisibility(View.GONE);
				holder.buttonModify.setVisibility(View.GONE);

				_listViewAccount.addView(view);

			}

		}

	}

	private void showListProducts()
	{

		_listViewProduct.removeAllViews();

		List<Product> productsList = _productSqLite.getAll();

		int totalProducts = (productsList != null) ? productsList.size() : 0;

		if (totalProducts != 0)
		{

			final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			for (int index = 0; index < totalProducts; index++)
			{

				View view = layoutInflater.inflate(
						R.layout.layout_config_one_product, null);
				ViewHolderProduct holder = new ViewHolderProduct();
				holder.buttonDelete = (Button) view.findViewById(R.id.button_config_item_delete);
				holder.buttonModify = (Button) view.findViewById(R.id.button_config_item_modify);
				holder.textProductCode = (TextView) view.findViewById(R.id.config_item_product_code);
				holder.textProductName = (TextView) view.findViewById(R.id.config_item_product_name);

				holder.textProductCode.setText(productsList.get(index).getCode());
				holder.textProductName.setText(productsList.get(index).getName());

				// not modified product
				holder.buttonDelete.setVisibility(View.GONE);
				holder.buttonModify.setVisibility(View.GONE);

				_listViewProduct.addView(view);

			}

		}
	}

	@Override
	protected void onDestroy()
	{
		System.gc();
		super.onDestroy();
	}

	@Override
	public void onNetworkMessageIncomming(Transaction transaction)
	{
		if (transaction == null)
		{
			Utils.debug("Null -----------received");
			return;
		}

		String message = transaction.getMessageReceived();
		Utils.debug("Receive message = " + message);

		if (message.equalsIgnoreCase(SERVICE.RESULT_OK))
		{
			Utils.debug("OK!!!!!!!!!!!");
			hideProgressDialog();

			return;
		}

		boolean isOnlyHideProgressDialog = false;
		if (transaction.getMethodSent().equals(SERVICE.GET_ACCOUNTS))
		{
			/* Process data get accounts */
			_accountSqLite.deleteAll();

			try
			{
				JSONArray jsonArray = new JSONArray(message);

				for (int i = 0; i < jsonArray.length(); i++)
				{
					JSONObject jsonObjectElement = jsonArray.getJSONObject(i);
					Account account = new Account();

					account.setAmount(jsonObjectElement.getInt(ACCOUNT.COLUMN_INDEX_AMOUNT
							+ ""));
					account.setActive(jsonObjectElement.getInt(ACCOUNT.COLUMN_INDEX_ACTIVE
							+ "") == 1 ? true : false);

					account.setDateCreated(jsonObjectElement.getLong(ACCOUNT.COLUMN_INDEX_DATE_CREATED
							+ ""));

					account.setGroupId(jsonObjectElement.getInt(ACCOUNT.COLUMN_INDEX_GROUP_ID
							+ ""));

					account.setPassword(jsonObjectElement.getString(ACCOUNT.COLUMN_INDEX_ID
							+ ""));

					account.setPinCode(jsonObjectElement.getString(ACCOUNT.COLUMN_INDEX_PASSWORD
							+ ""));
					account.setPositionId(jsonObjectElement.getInt(ACCOUNT.COLUMN_INDEX_POSITION_ID
							+ ""));

					account.setStaffId(jsonObjectElement.getString(ACCOUNT.COLUMN_INDEX_STAFF_ID
							+ ""));

					account.setTerminated(jsonObjectElement.getInt(ACCOUNT.COLUMN_INDEX_TERMINATED
							+ "") == 1 ? true : false);

					account.setUsername(jsonObjectElement.getString(ACCOUNT.COLUMN_INDEX_USER_NAME
							+ ""));

					_accountSqLite.insert(account);
				}

			} catch (JSONException e1)
			{
				e1.printStackTrace();
			}

		}
		else if (transaction.getMethodSent().equals(SERVICE.GET_PRODUCTS))
		{

			/* Process data get products */
			_productSqLite.deleteAll();

			List<Product> productsList = new ArrayList<Product>();

			try
			{
				JSONArray jsonArray = new JSONArray(message);

				for (int i = 0; i < jsonArray.length(); i++)
				{
					JSONObject jsonObjectElement = jsonArray.getJSONObject(i);
					Product product = new Product();

					// product.setImageName(jsonObjectElement
					// .getString(PRODUCT.COLUMN_INDEX_IMAGE_PATH + ""));

					// product.setPrice(jsonObjectElement
					// .getLong(PRODUCT.COLUMN_INDEX_PRICE_SELLING + ""));
					// product.setCode(jsonObjectElement
					// .getString(PRODUCT.COLUMN_INDEX_CODE + ""));
					// product.setGroupId(jsonObjectElement
					// .getInt(PRODUCT.COLUMN_INDEX_GROUP_ID + ""));
					// product.setName(jsonObjectElement
					// .getString(PRODUCT.COLUMN_INDEX_NAME + ""));

					product.setCode(jsonObjectElement.getString(PRODUCT.COLUMN_CODE));
					product.setName(jsonObjectElement.getString(PRODUCT.COLUMN_NAME));

					_productSqLite.insert(product);
					productsList.add(product);
				}

			} catch (JSONException e1)
			{
				e1.printStackTrace();
			}

			/* Update boxes */
			if (AppMain.getInstance().getListBoxItems() == null)
			{
				AppMain.getInstance().updateListBoxItems();
			}

		}
		else if (transaction.getMethodSent().equals(SERVICE.GET_BOX_CONFIG))
		{
			// Message received:
			// [{"BoxNumber":"1","ProductCode":"52164","RemainQuantity":"0","Price":"0"},{"BoxNumber":"2","ProductCode":"17930",...]

			List<Box> boxsList = new ArrayList<Box>();

			try
			{
				JSONArray jsonArray = new JSONArray(message);

				for (int i = 0; i < jsonArray.length(); i++)
				{
					JSONObject jsonObjectElement = jsonArray.getJSONObject(i);

					try
					{
						Box box = new Box();
						int id = Integer.parseInt(jsonObjectElement.getString(CONSTANTS.BOX.COLUMN_ID));
						if(id < 1)
						{
							Utils.debug("Wrong id!!!  " + id);
							continue;
						}
						
						box.setId(id);
						box.setCommand(String.format("%02d", (id - 1)));
						box.setProductAmount(Integer.parseInt(jsonObjectElement.getString(CONSTANTS.BOX.COLUMN_PRODUCT_AMOUNT)));
						box.setProductCode(jsonObjectElement.getString(CONSTANTS.BOX.COLUMN_PRODUCT_CODE));
						box.setProductPrice(Integer.parseInt(jsonObjectElement.getString(CONSTANTS.BOX.COLUMN_PRODUCT_PRICE)));
						
						Utils.debug("insert box " + box.getCommand());
						
						boxsList.add(box);

					} catch (NumberFormatException e)
					{
						e.printStackTrace();
					}
				}

				if (boxsList.size() == 0)
				{
					return;
				}
				
				if (boxsList.size() > 1)
				{
					Collections.sort(boxsList, new BoxCompartorByIdUp());
				}
				
			} catch (JSONException e1)
			{
				e1.printStackTrace();
			}

			BoxSQLite boxSQLite = new BoxSQLite(this);
			boxSQLite.deleteAll();

			for (Box box : boxsList)
			{
				boxSQLite.insert(box);
			}

			/* Update boxes */
			AppMain.getInstance().updateListBoxItems();

		}

		else
		{
			showDialogWithStatus(STATUS.SERVER_SEND_UNKNOWN_TYPE);
			isOnlyHideProgressDialog = true;
		}

		hideProgressDialog();
		if (!isOnlyHideProgressDialog)
			showDialogWithStatus(STATUS.SERVER_SEND_OK);
	}

	@Override
	public void onConnectFail(int typeError)
	{
		Utils.debug("Connect fail!.......................");
		hideProgressDialog();

		showDialogWithStatus(typeError);
	}

	private class BoxCompartorByIdUp implements Comparator<Box>
	{
		public int compare(Box one, Box another)
		{
			return (one.getId() < another.getId()) ? -1 : 1;
		}
	}
}
